
package org.upt.dcda;

import java.util.List;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.upt.dcda.db.AuthorEntity;
import org.upt.dcda.db.BookEntity;
import org.upt.dcda.db.BookReviewEntity;
import org.upt.dcda.db.BookTagEntity;
import org.upt.dcda.db.TagEntity;
import org.upt.dcda.db.UserEntity;
import org.upt.dcda.exceptions.AuthorNotFoundException;
import org.upt.dcda.exceptions.BookNotFoundException;
import org.upt.dcda.exceptions.BookstoreException;
import org.upt.dcda.exceptions.UserNotFoundException;

/**
 * Session Bean implementation class BookManagerBean
 */
@Stateless
@LocalBean
public class BookManagerBean implements BookManagerBeanRemote, BookManagerBeanLocal
{

	@PersistenceContext
	private EntityManager	entityManager;

	/**
	 * Default constructor.
	 */
	public BookManagerBean()
	{
	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public BookEntity addBook(String title, String description, int authorId, int price, int quantity)
			throws BookstoreException
	{
		try
		{
			AuthorEntity author = entityManager.find(AuthorEntity.class, authorId);
			if (author == null)
				throw new AuthorNotFoundException();

			BookEntity book = new BookEntity();

			book.setBookTitle(title);
			book.setBookDescription(description);
			book.setBookPrice(price);
			book.setBookQuantity(quantity);
			book.setAuthor(author);

			entityManager.persist(book);

			return book;
		}
		catch (BookstoreException be)
		{
			throw be;
		}
		catch (Throwable t)
		{
			throw new BookstoreException("Caught exception: " + t.toString(), t);
		}
	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public void modifyBook(int bookId, String title, String description, int authorId, int price)
			throws BookstoreException
	{
		try
		{
			BookEntity book = entityManager.find(BookEntity.class, bookId);

			if (book == null)
				throw new BookNotFoundException();

			AuthorEntity author = entityManager.find(AuthorEntity.class, authorId);

			if (author == null)
				throw new AuthorNotFoundException();

			book.setBookTitle(title);
			book.setBookDescription(description);
			book.setBookPrice(price);
			book.setAuthor(author);

			entityManager.persist(book);
		}
		catch (BookstoreException be)
		{
			throw be;
		}
		catch (Throwable t)
		{
			throw new BookstoreException("Caught exception: " + t.toString(), t);
		}
	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public void updateStock(int bookId, int stock) throws BookstoreException
	{
		try
		{
			BookEntity book = entityManager.find(BookEntity.class, bookId);

			if (book == null)
				throw new BookNotFoundException();

			book.setBookQuantity(book.getBookQuantity() + stock);
			entityManager.persist(book);
		}
		catch (BookstoreException be)
		{
			throw be;
		}
		catch (Throwable t)
		{
			throw new BookstoreException("Caught exception: " + t.toString(), t);
		}
	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public void deleteBook(int bookId) throws BookstoreException
	{
		BookEntity book = null;
		try
		{
			book = (BookEntity) entityManager.find(BookEntity.class, bookId);

			if (book != null)
			{
				entityManager.remove(book);
			}
			else
			{
				throw new BookNotFoundException();
			}
		}
		catch (Exception e)
		{
			throw new BookstoreException("Caught exception: " + e.toString(), e);
		}

	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public void addReview(int bookId, int userId, String content, int mark) throws BookstoreException
	{
		try
		{
			UserEntity user = entityManager.find(UserEntity.class, userId);
			if (user == null)
				throw new UserNotFoundException();

			BookEntity book = entityManager.find(BookEntity.class, bookId);
			if (book == null)
				throw new BookNotFoundException();

			BookReviewEntity bre = new BookReviewEntity();

			bre.setBookreviewContent(content);
			bre.setBookreviewMark(mark);
			bre.setBook(book);
			bre.setUser(user);

			entityManager.persist(bre);
		}
		catch (BookstoreException be)
		{
			throw be;
		}
		catch (Throwable t)
		{
			throw new BookstoreException("Caught exception: " + t.toString(), t);
		}
	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public BookEntity getBookById(int bookId) throws BookstoreException
	{
		try
		{
			BookEntity book = entityManager.find(BookEntity.class, bookId);
			if (book == null)
				throw new BookNotFoundException();
			return book;
		}
		catch (BookstoreException be)
		{
			throw be;
		}
		catch (Throwable t)
		{
			throw new BookstoreException("Caught exception: " + t.toString(), t);
		}
	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public List<BookReviewEntity> getBookReviewByBookId(int bookId) throws BookstoreException
	{
		try
		{
			Query query = entityManager.createNamedQuery(BookReviewEntity.VIEW_BOOK_REVIEW);
			query.setParameter("bookid", bookId);
			List<BookReviewEntity> resultList = (List<BookReviewEntity>) query.getResultList();
			return resultList;
		}
		catch (Throwable t)
		{
			throw new BookstoreException("Caught exception: " + t.toString(), t);
		}
	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public List<TagEntity> getBooktagsByBookId(int bookId) throws BookstoreException
	{
		try
		{
			Query query = entityManager.createNamedQuery(BookTagEntity.VIEW_BOOK_TAGS);
			query.setParameter("bookId", bookId);
			List<TagEntity> resultList = (List<TagEntity>) query.getResultList();
			return resultList;
		}
		catch (Throwable t)
		{
			throw new BookstoreException("Caught exception: " + t.toString(), t);
		}
	}
}
